<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Excel读取工具</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 15px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            overflow: hidden;
        }

        .header {
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }

        .header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
            font-weight: 300;
        }

        .header p {
            font-size: 1.1em;
            opacity: 0.9;
        }

        .main-content {
            padding: 40px;
        }

        .section {
            margin-bottom: 40px;
            padding: 30px;
            border: 1px solid #e0e0e0;
            border-radius: 10px;
            background: #fafafa;
        }

        .section h2 {
            color: #333;
            margin-bottom: 20px;
            font-size: 1.5em;
            border-bottom: 2px solid #4facfe;
            padding-bottom: 10px;
        }

        .form-group {
            margin-bottom: 20px;
        }

        .form-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #555;
        }

        .form-control {
            width: 100%;
            padding: 12px;
            border: 2px solid #ddd;
            border-radius: 8px;
            font-size: 14px;
            transition: border-color 0.3s;
        }

        .form-control:focus {
            outline: none;
            border-color: #4facfe;
            box-shadow: 0 0 0 3px rgba(79, 172, 254, 0.1);
        }

        .form-row {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
        }

        .file-upload {
            position: relative;
            display: inline-block;
            width: 100%;
        }

        .file-upload input[type=file] {
            position: absolute;
            opacity: 0;
            width: 100%;
            height: 100%;
            cursor: pointer;
        }

        .file-upload-label {
            display: block;
            padding: 20px;
            border: 2px dashed #4facfe;
            border-radius: 8px;
            text-align: center;
            background: #f8f9ff;
            cursor: pointer;
            transition: all 0.3s;
        }

        .file-upload-label:hover {
            background: #e8f4ff;
            border-color: #2196f3;
        }

        .file-upload-label.has-file {
            background: #e8f5e8;
            border-color: #4caf50;
            color: #2e7d32;
        }

        .btn {
            padding: 12px 30px;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s;
            margin-right: 10px;
            margin-bottom: 10px;
        }

        .btn-primary {
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            color: white;
        }

        .btn-primary:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(79, 172, 254, 0.4);
        }

        .btn-secondary {
            background: #6c757d;
            color: white;
        }

        .btn-secondary:hover {
            background: #5a6268;
        }

        .btn-danger {
            background: #dc3545;
            color: white;
        }

        .btn-danger:hover {
            background: #c82333;
        }

        .btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none !important;
        }

        .progress-container {
            margin: 20px 0;
            display: none;
        }

        .progress {
            width: 100%;
            height: 20px;
            background: #e0e0e0;
            border-radius: 10px;
            overflow: hidden;
        }

        .progress-bar {
            height: 100%;
            background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
            width: 0%;
            transition: width 0.3s;
            position: relative;
        }

        .progress-text {
            margin-top: 10px;
            text-align: center;
            font-weight: 600;
            color: #555;
        }

        .status-info {
            display: none;
            padding: 15px;
            border-radius: 8px;
            margin: 20px 0;
        }

        .status-info.success {
            background: #d4edda;
            border: 1px solid #c3e6cb;
            color: #155724;
        }

        .status-info.error {
            background: #f8d7da;
            border: 1px solid #f5c6cb;
            color: #721c24;
        }

        .status-info.info {
            background: #d1ecf1;
            border: 1px solid #bee5eb;
            color: #0c5460;
        }

        .results-container {
            display: none;
        }

        .results-table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
            background: white;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }

        .results-table th,
        .results-table td {
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #ddd;
        }

        .results-table th {
            background: #f8f9fa;
            font-weight: 600;
            color: #555;
        }

        .results-table tr:hover {
            background: #f5f5f5;
        }

        .loading {
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 3px solid #f3f3f3;
            border-top: 3px solid #4facfe;
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        .tab-container {
            margin-bottom: 30px;
        }

        .tab-buttons {
            display: flex;
            border-bottom: 2px solid #e0e0e0;
            margin-bottom: 20px;
        }

        .tab-button {
            padding: 12px 24px;
            background: none;
            border: none;
            cursor: pointer;
            font-size: 16px;
            font-weight: 600;
            color: #666;
            border-bottom: 3px solid transparent;
            transition: all 0.3s;
        }

        .tab-button.active {
            color: #4facfe;
            border-bottom-color: #4facfe;
        }

        .tab-content {
            display: none;
        }

        .tab-content.active {
            display: block;
        }

        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            margin: 20px 0;
        }

        .stat-card {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            text-align: center;
        }

        .stat-card h3 {
            color: #4facfe;
            font-size: 2em;
            margin-bottom: 10px;
        }

        .stat-card p {
            color: #666;
            font-weight: 600;
        }

        /* Sheet页选择样式 */
        .sheet-list {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
            gap: 15px;
            margin: 15px 0;
        }

        .sheet-item {
            background: white;
            border: 2px solid #e0e0e0;
            border-radius: 8px;
            padding: 15px;
            cursor: pointer;
            transition: all 0.3s;
            position: relative;
        }

        .sheet-item:hover {
            border-color: #4facfe;
            box-shadow: 0 2px 10px rgba(79, 172, 254, 0.2);
        }

        .sheet-item.selected {
            border-color: #4facfe;
            background: #f0f8ff;
        }

        .sheet-item.selected::after {
            content: '✓';
            position: absolute;
            top: 10px;
            right: 15px;
            color: #4facfe;
            font-weight: bold;
            font-size: 18px;
        }

        .sheet-name {
            font-weight: 600;
            color: #333;
            margin-bottom: 8px;
            font-size: 16px;
        }

        .sheet-details {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
            font-size: 14px;
            color: #666;
        }

        .sheet-detail {
            display: flex;
            justify-content: space-between;
        }

        .sheet-info {
            background: #f8f9fa;
            border: 1px solid #e0e0e0;
            border-radius: 8px;
            padding: 15px;
            margin-top: 10px;
        }

        .sheet-info.has-selection {
            background: #e8f5e8;
            border-color: #4caf50;
        }

        .sheet-info-title {
            font-weight: 600;
            color: #333;
            margin-bottom: 10px;
        }

        .sheet-info-details {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 10px;
        }

        .sheet-info-item {
            display: flex;
            justify-content: space-between;
            padding: 5px 0;
            border-bottom: 1px solid #eee;
        }

        .sheet-info-item:last-child {
            border-bottom: none;
        }

        .sheet-info-label {
            font-weight: 500;
            color: #555;
        }

        .sheet-info-value {
            color: #4facfe;
            font-weight: 600;
        }

        /* 数据展示相关样式 */
        .data-toolbar {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 20px 0;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
            border: 1px solid #e0e0e0;
        }

        .toolbar-left, .toolbar-right {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .search-input {
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 6px;
            font-size: 14px;
            width: 200px;
        }

        .search-input:focus {
            outline: none;
            border-color: #4facfe;
        }

        .page-size-select {
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 6px;
            font-size: 14px;
            background: white;
        }

        .table-container {
            overflow-x: auto;
            border: 1px solid #e0e0e0;
            border-radius: 8px;
            margin: 20px 0;
        }

        .data-table {
            width: 100%;
            border-collapse: collapse;
            background: white;
            font-size: 14px;
        }

        .data-table th {
            background: #f8f9fa;
            padding: 12px;
            text-align: left;
            border-bottom: 2px solid #e0e0e0;
            font-weight: 600;
            color: #555;
            position: sticky;
            top: 0;
            z-index: 10;
        }

        .data-table th:hover {
            background: #e9ecef;
            cursor: pointer;
        }

        .data-table th.sortable::after {
            content: ' ↕️';
            font-size: 12px;
        }

        .data-table th.sort-asc::after {
            content: ' ↑';
            color: #4facfe;
        }

        .data-table th.sort-desc::after {
            content: ' ↓';
            color: #4facfe;
        }

        .data-table td {
            padding: 10px 12px;
            border-bottom: 1px solid #f0f0f0;
            max-width: 200px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .data-table tr:hover {
            background: #f8f9fa;
        }

        .data-table tr:nth-child(even) {
            background: #fafafa;
        }

        .data-table tr:nth-child(even):hover {
            background: #f0f0f0;
        }

        .pagination-container {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 20px 0;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
            border: 1px solid #e0e0e0;
        }

        .pagination-info {
            font-size: 14px;
            color: #666;
        }

        .pagination-controls {
            display: flex;
            align-items: center;
            gap: 5px;
        }

        .btn-pagination {
            padding: 6px 12px;
            font-size: 14px;
            border: 1px solid #ddd;
            background: white;
            color: #555;
            border-radius: 4px;
            cursor: pointer;
            transition: all 0.2s;
        }

        .btn-pagination:hover:not(:disabled) {
            background: #4facfe;
            color: white;
            border-color: #4facfe;
        }

        .btn-pagination:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        .page-numbers {
            display: flex;
            gap: 2px;
            margin: 0 10px;
        }

        .page-number {
            padding: 6px 10px;
            font-size: 14px;
            border: 1px solid #ddd;
            background: white;
            color: #555;
            border-radius: 4px;
            cursor: pointer;
            transition: all 0.2s;
            min-width: 32px;
            text-align: center;
        }

        .page-number:hover {
            background: #e9ecef;
        }

        .page-number.active {
            background: #4facfe;
            color: white;
            border-color: #4facfe;
        }

        .page-number.ellipsis {
            cursor: default;
            background: transparent;
            border: none;
        }

        .page-number.ellipsis:hover {
            background: transparent;
        }

        /* 空数据状态 */
        .empty-state {
            text-align: center;
            padding: 60px 20px;
            color: #666;
        }

        .empty-state-icon {
            font-size: 48px;
            margin-bottom: 20px;
            opacity: 0.5;
        }

        .empty-state-text {
            font-size: 18px;
            margin-bottom: 10px;
        }

        .empty-state-subtext {
            font-size: 14px;
            opacity: 0.7;
        }

        /* 加载状态 */
        .loading-overlay {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(255, 255, 255, 0.8);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 100;
        }

        .loading-spinner {
            display: flex;
            align-items: center;
            gap: 10px;
            font-size: 16px;
            color: #4facfe;
        }

        /* 响应式设计 */
        @media (max-width: 768px) {
            .data-toolbar {
                flex-direction: column;
                gap: 15px;
            }

            .toolbar-left, .toolbar-right {
                width: 100%;
                justify-content: center;
            }

            .search-input {
                width: 100%;
                max-width: 300px;
            }

            .pagination-container {
                flex-direction: column;
                gap: 15px;
            }

            .pagination-controls {
                flex-wrap: wrap;
                justify-content: center;
            }

            .data-table th,
            .data-table td {
                padding: 8px;
                font-size: 12px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>📊 Excel读取工具</h1>
            <p>高性能多线程Excel文件读取与处理</p>
        </div>

        <div class="main-content">
            <!-- 文件上传区域 -->
            <div class="section">
                <h2>📁 文件上传</h2>
                <div class="form-group">
                    <label for="fileInput">选择Excel文件</label>
                    <div class="file-upload">
                        <input type="file" id="fileInput" accept=".xlsx,.xls" />
                        <label for="fileInput" class="file-upload-label" id="fileLabel">
                            <div>📎 点击选择Excel文件或拖拽文件到此处</div>
                            <small>支持 .xlsx 和 .xls 格式</small>
                        </label>
                    </div>
                </div>
            </div>

            <!-- Sheet页选择区域 -->
            <div class="section" id="sheetSection" style="display: none;">
                <h2>📋 工作表选择</h2>
                <div class="form-group">
                    <button type="button" class="btn btn-secondary" onclick="loadSheetList()">🔄 加载工作表列表</button>
                    <div id="sheetLoading" class="loading" style="display: none;">正在加载工作表信息...</div>
                </div>
                <div id="sheetListContainer" style="display: none;">
                    <div class="form-group">
                        <label>可用工作表：</label>
                        <div id="sheetList" class="sheet-list">
                            <!-- 动态生成的sheet列表 -->
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="selectedSheetInfo">选中工作表信息：</label>
                        <div id="selectedSheetInfo" class="sheet-info">
                            请选择一个工作表
                        </div>
                    </div>
                </div>
            </div>

            <!-- 读取配置 -->
            <div class="section">
                <h2>⚙️ 读取配置</h2>
                <div class="tab-container">
                    <div class="tab-buttons">
                        <button class="tab-button active" onclick="switchTab('sync')">同步读取</button>
                        <button class="tab-button" onclick="switchTab('async')">异步读取</button>
                        <button class="tab-button" onclick="switchTab('sharding')">分片读取</button>
                    </div>

                    <div id="sync-tab" class="tab-content active">
                        <div class="form-row">
                            <div class="form-group">
                                <label for="sheetName">工作表名称</label>
                                <input type="text" id="sheetName" class="form-control" placeholder="留空读取第一个工作表">
                            </div>
                            <div class="form-group">
                                <label for="sheetIndex">工作表索引</label>
                                <input type="number" id="sheetIndex" class="form-control" value="0" min="0">
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-group">
                                <label for="startRow">起始行</label>
                                <input type="number" id="startRow" class="form-control" value="1" min="1">
                            </div>
                            <div class="form-group">
                                <label for="endRow">结束行</label>
                                <input type="number" id="endRow" class="form-control" placeholder="留空读取到最后一行">
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-group">
                                <label>
                                    <input type="checkbox" id="hasHeader" checked> 包含表头
                                </label>
                            </div>
                            <div class="form-group">
                                <label>
                                    <input type="checkbox" id="skipEmptyRows" checked> 跳过空行
                                </label>
                            </div>
                        </div>
                        <button class="btn btn-primary" onclick="readExcelSync()">
                            <span class="loading" id="syncLoading" style="display: none;"></span>
                            开始同步读取
                        </button>
                    </div>

                    <div id="async-tab" class="tab-content">
                        <div class="form-row">
                            <div class="form-group">
                                <label for="asyncSheetName">工作表名称</label>
                                <input type="text" id="asyncSheetName" class="form-control" placeholder="留空读取第一个工作表">
                            </div>
                            <div class="form-group">
                                <label for="asyncSheetIndex">工作表索引</label>
                                <input type="number" id="asyncSheetIndex" class="form-control" value="0" min="0">
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-group">
                                <label>
                                    <input type="checkbox" id="asyncHasHeader" checked> 包含表头
                                </label>
                            </div>
                            <div class="form-group">
                                <label>
                                    <input type="checkbox" id="asyncSkipEmptyRows" checked> 跳过空行
                                </label>
                            </div>
                        </div>
                        <button class="btn btn-primary" onclick="readExcelAsync()">
                            <span class="loading" id="asyncLoading" style="display: none;"></span>
                            开始异步读取
                        </button>
                        <button class="btn btn-danger" onclick="cancelAsyncTask()" id="cancelBtn" style="display: none;">
                            取消任务
                        </button>
                    </div>

                    <div id="sharding-tab" class="tab-content">
                        <div class="form-row">
                            <div class="form-group">
                                <label for="shardingSheetName">工作表名称</label>
                                <input type="text" id="shardingSheetName" class="form-control" placeholder="留空读取第一个工作表">
                            </div>
                            <div class="form-group">
                                <label for="shardingSheetIndex">工作表索引</label>
                                <input type="number" id="shardingSheetIndex" class="form-control" value="0" min="0">
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-group">
                                <label for="shardSize">分片大小</label>
                                <input type="number" id="shardSize" class="form-control" value="5000" min="1000">
                            </div>
                            <div class="form-group">
                                <label for="maxShards">最大分片数</label>
                                <input type="number" id="maxShards" class="form-control" value="10" min="1">
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-group">
                                <label>
                                    <input type="checkbox" id="shardingHasHeader" checked> 包含表头
                                </label>
                            </div>
                            <div class="form-group">
                                <label>
                                    <input type="checkbox" id="shardingSkipEmptyRows" checked> 跳过空行
                                </label>
                            </div>
                        </div>
                        <button class="btn btn-primary" onclick="readExcelSharding()">
                            <span class="loading" id="shardingLoading" style="display: none;"></span>
                            开始分片读取
                        </button>
                        <button class="btn btn-danger" onclick="cancelShardingTask()" id="cancelShardingBtn" style="display: none;">
                            取消任务
                        </button>
                    </div>
                </div>
            </div>

            <!-- 进度显示 -->
            <div class="progress-container" id="progressContainer">
                <h3>📈 读取进度</h3>
                <div class="progress">
                    <div class="progress-bar" id="progressBar"></div>
                </div>
                <div class="progress-text" id="progressText">准备中...</div>
            </div>

            <!-- 状态信息 -->
            <div class="status-info" id="statusInfo"></div>

            <!-- 结果展示 -->
            <div id="resultsContainer" class="results-container" style="display: none;">
                <h3>📊 数据展示</h3>
                
                <!-- 统计信息 -->
                <div id="statsGrid" class="stats-grid"></div>
                
                <!-- 数据操作工具栏 -->
                <div class="data-toolbar">
                    <div class="toolbar-left">
                        <input type="text" id="searchInput" placeholder="搜索数据..." class="search-input">
                        <button onclick="searchData()" class="btn btn-secondary">🔍 搜索</button>
                        <button onclick="clearSearch()" class="btn btn-secondary">🗑️ 清除</button>
                    </div>
                    <div class="toolbar-right">
                        <select id="pageSizeSelect" onchange="changePageSize()" class="page-size-select">
                            <option value="10">每页 10 行</option>
                            <option value="25" selected>每页 25 行</option>
                            <option value="50">每页 50 行</option>
                            <option value="100">每页 100 行</option>
                            <option value="-1">显示全部</option>
                        </select>
                        <button onclick="exportData()" class="btn btn-secondary">📥 导出</button>
                    </div>
                </div>
                
                <!-- 数据表格 -->
                <div class="table-container">
                    <table class="data-table">
                        <thead id="tableHeader"></thead>
                        <tbody id="tableBody"></tbody>
                    </table>
                </div>
                
                <!-- 分页控件 -->
                <div id="paginationContainer" class="pagination-container">
                    <div class="pagination-info">
                        <span id="paginationInfo">显示第 1-25 条，共 0 条记录</span>
                    </div>
                    <div class="pagination-controls">
                        <button onclick="goToPage(1)" class="btn btn-pagination" id="firstPageBtn">首页</button>
                        <button onclick="goToPage(currentPage - 1)" class="btn btn-pagination" id="prevPageBtn">上一页</button>
                        <span class="page-numbers" id="pageNumbers"></span>
                        <button onclick="goToPage(currentPage + 1)" class="btn btn-pagination" id="nextPageBtn">下一页</button>
                        <button onclick="goToPage(totalPages)" class="btn btn-pagination" id="lastPageBtn">末页</button>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        let currentRequestId = null;
        let progressInterval = null;
        let currentFilePath = null;
        let selectedSheetInfo = null;

        // 文件上传处理
        document.getElementById('fileInput').addEventListener('change', function(e) {
            const file = e.target.files[0];
            const label = document.getElementById('fileLabel');
            const sheetSection = document.getElementById('sheetSection');
            
            if (file) {
                label.innerHTML = `
                    <div>✅ ${file.name}</div>
                    <small>文件大小: ${(file.size / 1024 / 1024).toFixed(2)} MB</small>
                `;
                label.classList.add('has-file');
                
                // 显示sheet选择区域
                sheetSection.style.display = 'block';
                
                // 重置sheet相关状态
                resetSheetSelection();
            } else {
                label.innerHTML = `
                    <div>📎 点击选择Excel文件或拖拽文件到此处</div>
                    <small>支持 .xlsx 和 .xls 格式</small>
                `;
                label.classList.remove('has-file');
                
                // 隐藏sheet选择区域
                sheetSection.style.display = 'none';
                resetSheetSelection();
            }
        });

        // 重置sheet选择状态
        function resetSheetSelection() {
            currentFilePath = null;
            selectedSheetInfo = null;
            document.getElementById('sheetListContainer').style.display = 'none';
            document.getElementById('sheetList').innerHTML = '';
            document.getElementById('selectedSheetInfo').innerHTML = '请选择一个工作表';
            document.getElementById('selectedSheetInfo').className = 'sheet-info';
        }

        // 加载工作表列表
        async function loadSheetList() {
            const file = getSelectedFile();
            if (!file) return;

            const loading = document.getElementById('sheetLoading');
            loading.style.display = 'inline-block';
            hideStatus();

            try {
                // 先上传文件获取文件路径
                currentFilePath = await uploadFile(file);
                
                // 获取工作表信息
                const response = await fetch(`/api/excel/sheets?filePath=${encodeURIComponent(currentFilePath)}`);
                const result = await response.json();
                
                if (response.ok && result.success) {
                    displaySheetList(result.sheets);
                    showStatus('✅ 工作表列表加载成功！', 'success');
                    setTimeout(hideStatus, 3000);
                } else {
                    showStatus(`❌ 加载工作表失败: ${result.message || '未知错误'}`, 'error');
                }
            } catch (error) {
                showStatus(`❌ 加载工作表失败: ${error.message}`, 'error');
            } finally {
                loading.style.display = 'none';
            }
        }

        // 显示工作表列表
        function displaySheetList(sheets) {
            const sheetList = document.getElementById('sheetList');
            const sheetListContainer = document.getElementById('sheetListContainer');
            
            sheetList.innerHTML = '';
            
            sheets.forEach((sheet, index) => {
                const sheetItem = document.createElement('div');
                sheetItem.className = 'sheet-item';
                sheetItem.onclick = () => selectSheet(sheet, sheetItem);
                
                sheetItem.innerHTML = `
                    <div class="sheet-name">${sheet.sheetName}</div>
                    <div class="sheet-details">
                        <div class="sheet-detail">
                            <span>索引:</span>
                            <span>${sheet.sheetIndex}</span>
                        </div>
                        <div class="sheet-detail">
                            <span>行数:</span>
                            <span>${sheet.totalRows}</span>
                        </div>
                        <div class="sheet-detail">
                            <span>列数:</span>
                            <span>${sheet.totalColumns}</span>
                        </div>
                        <div class="sheet-detail">
                            <span>数据行:</span>
                            <span>${sheet.totalRows > 0 ? sheet.totalRows - (sheet.hasHeader ? 1 : 0) : 0}</span>
                        </div>
                    </div>
                `;
                
                sheetList.appendChild(sheetItem);
            });
            
            sheetListContainer.style.display = 'block';
        }

        // 选择工作表
        function selectSheet(sheet, element) {
            // 移除其他选中状态
            document.querySelectorAll('.sheet-item').forEach(item => {
                item.classList.remove('selected');
            });
            
            // 添加选中状态
            element.classList.add('selected');
            selectedSheetInfo = sheet;
            
            // 更新选中工作表信息显示
            const selectedSheetInfoDiv = document.getElementById('selectedSheetInfo');
            selectedSheetInfoDiv.className = 'sheet-info has-selection';
            selectedSheetInfoDiv.innerHTML = `
                <div class="sheet-info-title">已选择工作表: ${sheet.sheetName}</div>
                <div class="sheet-info-details">
                    <div class="sheet-info-item">
                        <span class="sheet-info-label">工作表索引:</span>
                        <span class="sheet-info-value">${sheet.sheetIndex}</span>
                    </div>
                    <div class="sheet-info-item">
                        <span class="sheet-info-label">总行数:</span>
                        <span class="sheet-info-value">${sheet.totalRows}</span>
                    </div>
                    <div class="sheet-info-item">
                        <span class="sheet-info-label">总列数:</span>
                        <span class="sheet-info-value">${sheet.totalColumns}</span>
                    </div>
                    <div class="sheet-info-item">
                        <span class="sheet-info-label">包含表头:</span>
                        <span class="sheet-info-value">${sheet.hasHeader ? '是' : '否'}</span>
                    </div>
                </div>
            `;
            
            // 自动填充读取配置
            fillReadingConfig(sheet);
        }

        // 自动填充读取配置
        function fillReadingConfig(sheet) {
            // 同步读取配置
            document.getElementById('sheetName').value = sheet.sheetName;
            document.getElementById('sheetIndex').value = sheet.sheetIndex;
            document.getElementById('hasHeader').checked = sheet.hasHeader;
            
            // 异步读取配置
            document.getElementById('asyncSheetName').value = sheet.sheetName;
            document.getElementById('asyncSheetIndex').value = sheet.sheetIndex;
            document.getElementById('asyncHasHeader').checked = sheet.hasHeader;
            
            // 分片读取配置
            document.getElementById('shardingSheetName').value = sheet.sheetName;
            document.getElementById('shardingSheetIndex').value = sheet.sheetIndex;
            document.getElementById('shardingHasHeader').checked = sheet.hasHeader;
        }

        // 标签页切换
        function switchTab(tabName) {
            // 隐藏所有标签页内容
            document.querySelectorAll('.tab-content').forEach(tab => {
                tab.classList.remove('active');
            });
            
            // 移除所有按钮的激活状态
            document.querySelectorAll('.tab-button').forEach(btn => {
                btn.classList.remove('active');
            });
            
            // 显示选中的标签页
            document.getElementById(tabName + '-tab').classList.add('active');
            event.target.classList.add('active');
        }

        // 显示状态信息
        function showStatus(message, type = 'info') {
            const statusInfo = document.getElementById('statusInfo');
            statusInfo.className = `status-info ${type}`;
            statusInfo.innerHTML = message;
            statusInfo.style.display = 'block';
        }

        // 隐藏状态信息
        function hideStatus() {
            document.getElementById('statusInfo').style.display = 'none';
        }

        // 显示进度
        function showProgress() {
            document.getElementById('progressContainer').style.display = 'block';
        }

        // 隐藏进度
        function hideProgress() {
            document.getElementById('progressContainer').style.display = 'none';
            if (progressInterval) {
                clearInterval(progressInterval);
                progressInterval = null;
            }
        }

        // 更新进度
        function updateProgress(percentage, text) {
            document.getElementById('progressBar').style.width = percentage + '%';
            document.getElementById('progressText').textContent = text;
        }

        // 获取文件
        function getSelectedFile() {
            const fileInput = document.getElementById('fileInput');
            if (!fileInput.files[0]) {
                showStatus('请先选择Excel文件', 'error');
                return null;
            }
            return fileInput.files[0];
        }

        // 上传文件并获取文件路径
        async function uploadFile(file) {
            const formData = new FormData();
            formData.append('file', file);

            const response = await fetch('/api/excel/upload', {
                method: 'POST',
                body: formData
            });

            const result = await response.json();
            
            if (!response.ok || !result.success) {
                throw new Error(result.message || '文件上传失败');
            }

            return result.filePath;
        }

        // 同步读取Excel
        async function readExcelSync() {
            const file = getSelectedFile();
            if (!file) return;

            const loading = document.getElementById('syncLoading');
            loading.style.display = 'inline-block';
            hideStatus();
            hideProgress();

            try {
                // 先上传文件
                const filePath = await uploadFile(file);
                
                // 构建请求参数
                const request = {
                    requestId: generateRequestId(),
                    filePath: filePath,
                    sheetName: document.getElementById('sheetName').value || null,
                    sheetIndex: parseInt(document.getElementById('sheetIndex').value) || 0,
                    startRow: parseInt(document.getElementById('startRow').value) || 1,
                    endRow: document.getElementById('endRow').value ? parseInt(document.getElementById('endRow').value) : null,
                    hasHeader: document.getElementById('hasHeader').checked,
                    skipEmptyRows: document.getElementById('skipEmptyRows').checked
                };

                const response = await fetch('/api/excel/read/sync', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(request)
                });

                const result = await response.json();
                
                if (response.ok && result.status === 'SUCCESS') {
                    showStatus('✅ 文件读取成功！', 'success');
                    displayResults(result);
                } else {
                    showStatus(`❌ 读取失败: ${result.message || '未知错误'}`, 'error');
                }
            } catch (error) {
                showStatus(`❌ 读取失败: ${error.message}`, 'error');
            } finally {
                loading.style.display = 'none';
            }
        }

        // 异步读取Excel
        async function readExcelAsync() {
            const file = getSelectedFile();
            if (!file) return;

            const loading = document.getElementById('asyncLoading');
            loading.style.display = 'inline-block';
            hideStatus();
            showProgress();

            try {
                // 先上传文件
                const filePath = await uploadFile(file);
                
                // 构建请求参数
                const request = {
                    requestId: generateRequestId(),
                    filePath: filePath,
                    sheetName: document.getElementById('asyncSheetName').value || null,
                    sheetIndex: parseInt(document.getElementById('asyncSheetIndex').value) || 0,
                    hasHeader: document.getElementById('asyncHasHeader').checked,
                    skipEmptyRows: document.getElementById('asyncSkipEmptyRows').checked
                };

                const response = await fetch('/api/excel/read/async', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(request)
                });

                const result = await response.json();
                
                if (response.ok && result.requestId) {
                    currentRequestId = result.requestId;
                    showStatus('📤 任务已提交，正在处理中...', 'info');
                    document.getElementById('cancelBtn').style.display = 'inline-block';
                    startProgressTracking();
                } else {
                    showStatus(`❌ 提交失败: ${result.message || '未知错误'}`, 'error');
                    hideProgress();
                }
            } catch (error) {
                showStatus(`❌ 读取失败: ${error.message}`, 'error');
                hideProgress();
            } finally {
                loading.style.display = 'none';
            }
        }

        // 分片读取Excel
        async function readExcelSharding() {
            const file = getSelectedFile();
            if (!file) return;

            const loading = document.getElementById('shardingLoading');
            loading.style.display = 'inline-block';
            hideStatus();
            showProgress();

            try {
                // 先上传文件
                const filePath = await uploadFile(file);
                
                // 构建请求参数
                const request = {
                    requestId: generateRequestId(),
                    filePath: filePath,
                    sheetName: document.getElementById('shardingSheetName').value || null,
                    sheetIndex: parseInt(document.getElementById('shardingSheetIndex').value) || 0,
                    shardSize: parseInt(document.getElementById('shardSize').value) || 5000,
                    maxShards: parseInt(document.getElementById('maxShards').value) || 10,
                    hasHeader: document.getElementById('shardingHasHeader').checked,
                    skipEmptyRows: document.getElementById('shardingSkipEmptyRows').checked
                };

                const response = await fetch('/api/excel/read/sharding', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(request)
                });

                const result = await response.json();
                
                if (response.ok && result.requestId) {
                    currentRequestId = result.requestId;
                    showStatus('📤 分片任务已提交，正在处理中...', 'info');
                    document.getElementById('cancelShardingBtn').style.display = 'inline-block';
                    startProgressTracking();
                } else {
                    showStatus(`❌ 提交失败: ${result.message || '未知错误'}`, 'error');
                    hideProgress();
                }
            } catch (error) {
                showStatus(`❌ 读取失败: ${error.message}`, 'error');
                hideProgress();
            } finally {
                loading.style.display = 'none';
            }
        }

        // 生成请求ID
        function generateRequestId() {
            return 'req_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
        }

        // 开始进度跟踪
        function startProgressTracking() {
            if (progressInterval) {
                clearInterval(progressInterval);
            }

            progressInterval = setInterval(async () => {
                if (!currentRequestId) return;

                try {
                    const response = await fetch(`/api/excel/progress/${currentRequestId}`);
                    const result = await response.json();

                    if (response.ok) {
                        const progress = result.progress || 0;
                        const status = result.status || 'RUNNING';
                        
                        updateProgress(progress * 100, `进度: ${(progress * 100).toFixed(1)}% - ${status}`);

                        if (status === 'COMPLETED') {
                            // 获取最终结果
                            await getTaskResult();
                        } else if (status === 'FAILED' || status === 'CANCELLED') {
                            showStatus(`❌ 任务${status === 'FAILED' ? '失败' : '已取消'}`, 'error');
                            hideProgress();
                            resetButtons();
                        }
                    }
                } catch (error) {
                    console.error('获取进度失败:', error);
                }
            }, 1000);
        }

        // 获取任务结果
        async function getTaskResult() {
            try {
                const response = await fetch(`/api/excel/result/${currentRequestId}`);
                const result = await response.json();
                
                if (response.ok && result.status === 'SUCCESS') {
                    showStatus('✅ 任务完成！', 'success');
                    displayResults(result);
                } else {
                    showStatus(`❌ 获取结果失败: ${result.message || '未知错误'}`, 'error');
                }
            } catch (error) {
                showStatus(`❌ 获取结果失败: ${error.message}`, 'error');
            }
            
            updateProgress(100, '任务完成');
            hideProgress();
            resetButtons();
        }

        // 取消异步任务
        async function cancelAsyncTask() {
            if (!currentRequestId) return;

            try {
                const response = await fetch(`/api/excel/cancel/${currentRequestId}`, {
                    method: 'DELETE'
                });

                if (response.ok) {
                    showStatus('✅ 任务已取消', 'info');
                } else {
                    showStatus('❌ 取消任务失败', 'error');
                }
            } catch (error) {
                showStatus(`❌ 取消请求失败: ${error.message}`, 'error');
            }

            resetButtons();
            hideProgress();
        }

        // 取消分片任务
        async function cancelShardingTask() {
            await cancelAsyncTask(); // 使用相同的取消逻辑
        }

        // 重置按钮状态
        function resetButtons() {
            document.getElementById('cancelBtn').style.display = 'none';
            document.getElementById('cancelShardingBtn').style.display = 'none';
            currentRequestId = null;
        }

        // 显示结果
        function displayResults(result) {
            const container = document.getElementById('resultsContainer');
            const statsGrid = document.getElementById('statsGrid');

            // 保存数据
            currentData = result.data || [];
            filteredData = [...currentData];
            
            // 重置分页
            currentPage = 1;
            sortColumn = null;
            sortDirection = 'asc';

            // 显示统计信息
            statsGrid.innerHTML = `
                <div class="stat-card">
                    <h3>${result.totalRows || 0}</h3>
                    <p>总行数</p>
                </div>
                <div class="stat-card">
                    <h3>${result.totalColumns || 0}</h3>
                    <p>总列数</p>
                </div>
                <div class="stat-card">
                    <h3>${result.sheetName || 'N/A'}</h3>
                    <p>工作表名称</p>
                </div>
                <div class="stat-card">
                    <h3>${result.processingTime || 0}ms</h3>
                    <p>处理时间</p>
                </div>
            `;

            // 渲染数据表格
            renderDataTable();
            
            container.style.display = 'block';
        }

        // 渲染数据表格
        function renderDataTable() {
            const tableHeader = document.getElementById('tableHeader');
            const tableBody = document.getElementById('tableBody');
            
            if (!filteredData || filteredData.length === 0) {
                tableHeader.innerHTML = '';
                tableBody.innerHTML = `
                    <tr>
                        <td colspan="100%" class="empty-state">
                            <div class="empty-state-icon">📄</div>
                            <div class="empty-state-text">暂无数据</div>
                            <div class="empty-state-subtext">请检查文件内容或调整筛选条件</div>
                        </td>
                    </tr>
                `;
                updatePagination();
                return;
            }

            // 生成表头
            const headers = Object.keys(filteredData[0]);
            tableHeader.innerHTML = '<tr>' + headers.map(h => 
                `<th class="sortable" onclick="sortData('${h}')">${h}</th>`
            ).join('') + '</tr>';

            // 计算分页
            const startIndex = (currentPage - 1) * pageSize;
            const endIndex = pageSize === -1 ? filteredData.length : startIndex + pageSize;
            const pageData = filteredData.slice(startIndex, endIndex);

            // 生成表格数据
            tableBody.innerHTML = pageData.map(row => 
                '<tr>' + headers.map(h => `<td title="${row[h] || ''}">${row[h] || ''}</td>`).join('') + '</tr>'
            ).join('');

            // 更新分页信息
            updatePagination();
        }

        // 排序数据
        function sortData(column) {
            if (sortColumn === column) {
                sortDirection = sortDirection === 'asc' ? 'desc' : 'asc';
            } else {
                sortColumn = column;
                sortDirection = 'asc';
            }

            filteredData.sort((a, b) => {
                let aVal = a[column] || '';
                let bVal = b[column] || '';
                
                // 尝试转换为数字
                const aNum = parseFloat(aVal);
                const bNum = parseFloat(bVal);
                
                if (!isNaN(aNum) && !isNaN(bNum)) {
                    return sortDirection === 'asc' ? aNum - bNum : bNum - aNum;
                }
                
                // 字符串比较
                aVal = aVal.toString().toLowerCase();
                bVal = bVal.toString().toLowerCase();
                
                if (sortDirection === 'asc') {
                    return aVal.localeCompare(bVal);
                } else {
                    return bVal.localeCompare(aVal);
                }
            });

            // 更新表头样式
            document.querySelectorAll('.data-table th').forEach(th => {
                th.className = 'sortable';
            });
            
            const currentTh = document.querySelector(`th[onclick="sortData('${column}')"]`);
            if (currentTh) {
                currentTh.className = `sortable sort-${sortDirection}`;
            }

            currentPage = 1;
            renderDataTable();
        }

        // 搜索数据
        function searchData() {
            const searchTerm = document.getElementById('searchInput').value.toLowerCase().trim();
            
            if (!searchTerm) {
                filteredData = [...currentData];
            } else {
                filteredData = currentData.filter(row => {
                    return Object.values(row).some(value => 
                        value && value.toString().toLowerCase().includes(searchTerm)
                    );
                });
            }
            
            currentPage = 1;
            renderDataTable();
        }

        // 清除搜索
        function clearSearch() {
            document.getElementById('searchInput').value = '';
            filteredData = [...currentData];
            currentPage = 1;
            renderDataTable();
        }

        // 改变页面大小
        function changePageSize() {
            pageSize = parseInt(document.getElementById('pageSizeSelect').value);
            currentPage = 1;
            renderDataTable();
        }

        // 跳转到指定页面
        function goToPage(page) {
            if (page < 1 || page > totalPages) return;
            currentPage = page;
            renderDataTable();
        }

        // 更新分页信息
        function updatePagination() {
            const paginationInfo = document.getElementById('paginationInfo');
            const paginationContainer = document.getElementById('paginationContainer');
            const pageNumbers = document.getElementById('pageNumbers');
            
            if (pageSize === -1) {
                totalPages = 1;
                paginationInfo.textContent = `显示全部 ${filteredData.length} 条记录`;
                paginationContainer.style.display = filteredData.length > 0 ? 'flex' : 'none';
                pageNumbers.innerHTML = '';
                return;
            }

            totalPages = Math.ceil(filteredData.length / pageSize);
            const startIndex = (currentPage - 1) * pageSize + 1;
            const endIndex = Math.min(currentPage * pageSize, filteredData.length);
            
            paginationInfo.textContent = `显示第 ${startIndex}-${endIndex} 条，共 ${filteredData.length} 条记录`;
            
            // 更新按钮状态
            document.getElementById('firstPageBtn').disabled = currentPage === 1;
            document.getElementById('prevPageBtn').disabled = currentPage === 1;
            document.getElementById('nextPageBtn').disabled = currentPage === totalPages;
            document.getElementById('lastPageBtn').disabled = currentPage === totalPages;
            
            // 生成页码
            generatePageNumbers();
            
            paginationContainer.style.display = totalPages > 1 ? 'flex' : 'none';
        }

        // 生成页码
        function generatePageNumbers() {
            const pageNumbers = document.getElementById('pageNumbers');
            const maxVisiblePages = 5;
            let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
            let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);
            
            if (endPage - startPage + 1 < maxVisiblePages) {
                startPage = Math.max(1, endPage - maxVisiblePages + 1);
            }
            
            let html = '';
            
            if (startPage > 1) {
                html += '<span class="page-number" onclick="goToPage(1)">1</span>';
                if (startPage > 2) {
                    html += '<span class="page-number ellipsis">...</span>';
                }
            }
            
            for (let i = startPage; i <= endPage; i++) {
                html += `<span class="page-number ${i === currentPage ? 'active' : ''}" onclick="goToPage(${i})">${i}</span>`;
            }
            
            if (endPage < totalPages) {
                if (endPage < totalPages - 1) {
                    html += '<span class="page-number ellipsis">...</span>';
                }
                html += `<span class="page-number" onclick="goToPage(${totalPages})">${totalPages}</span>`;
            }
            
            pageNumbers.innerHTML = html;
        }

        // 导出数据
        function exportData() {
            if (!filteredData || filteredData.length === 0) {
                showStatus('没有数据可导出', 'error');
                return;
            }

            const headers = Object.keys(filteredData[0]);
            let csvContent = headers.join(',') + '\n';
            
            filteredData.forEach(row => {
                const values = headers.map(header => {
                    const value = row[header] || '';
                    // 处理包含逗号或引号的值
                    if (value.toString().includes(',') || value.toString().includes('"')) {
                        return '"' + value.toString().replace(/"/g, '""') + '"';
                    }
                    return value;
                });
                csvContent += values.join(',') + '\n';
            });

            // 创建下载链接
            const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
            const link = document.createElement('a');
            const url = URL.createObjectURL(blob);
            link.setAttribute('href', url);
            link.setAttribute('download', `excel_data_${new Date().getTime()}.csv`);
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            
            showStatus('✅ 数据导出成功！', 'success');
            setTimeout(hideStatus, 3000);
        }

        // 页面加载完成后的初始化
        document.addEventListener('DOMContentLoaded', function() {
            // 检查服务状态
            fetch('/api/excel/health')
                .then(response => response.json())
                .then(result => {
                    if (result.status === 'UP') {
                        showStatus('🟢 Excel读取服务运行正常', 'success');
                        setTimeout(hideStatus, 3000);
                    }
                })
                .catch(error => {
                    showStatus('🔴 Excel读取服务连接失败', 'error');
                });
                
            // 绑定搜索框回车事件
            document.getElementById('searchInput').addEventListener('keypress', function(e) {
                if (e.key === 'Enter') {
                    searchData();
                }
            });
        });
    </script>
</body>
</html>